import pprint
from datetime import datetime, timedelta
from typing import List

from bson import ObjectId
from fastapi import APIRouter

import schemas
from components.router import CenterRoute
from controller.statistic import activity
from ioservice.common.mongo import aggregate_docs
from ioservice.const import activity_col, activity_register_col, institution_col
from schemas import ActivityStatisticParams
from task_utils.task_es import job_delete_institutions, job_task_institution_overview, job_task_update_dept_to_es, \
    job_task_update_activity_span, job_task_radar

router = APIRouter(route_class=CenterRoute)


@router.post("/stats/activities", response_model=List[schemas.AggregateResult])
async def stats_activities(params: schemas.ActivityStatisticParams):
    return await activity.do_stats_activity(params)


@router.post("/stats/register_records", response_model=List[schemas.AggregateResult])
async def stats_activity_registers(params: schemas.RegisterRecordStatisticParams):
    return await activity.do_stats_activity_register(params)


@router.post("/desk/stats/activities", description="近期活动")
async def stats_activities():
    """
    aggregate_docs(activity_register_col, pipeline)
    """
    pipeline = [
        {"$match": {"is_deleted": {"$ne": True}}},
        {"$project": {"end_time": 1, "name": 1, "name_zh": 1, "activity_type": 1, "region": 1, "institution_id": 1,
                      "images": 1}},
        # #获得机构的名字
        {
            "$lookup": {
                "from": "institution",
                "localField": "institution_id",
                "foreignField": "_id",
                "as": "institution_info"
            }
        },
        {"$lookup": {
            "from": "institution",
            "let": {"institution_id": "$institution_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$institution_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"institution_name": 1, "_id": 0}}
            ],
            "as": 'institutions'
        }},
        # 活动报名人数 2排序
        {"$lookup": {
            "from": "activity_register",
            "let": {"activity_ref_id": "$_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$activity_id", "$$activity_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"person_id": 1, "refs_participants": 1}},
            ],
            "as": 'participants'
        }},
        {"$addFields": {"numOfParticipants": {"$size": "$participants"}}},
        {"$sort": {"end_time": -1, "numOfParticipants": -1}},
        # 保留前5的人
        {"$addFields": {"fives": {"$slice": ["$participants", 5]}}},
        {"$unwind": "$fives"},
        {"$unset": ["participants"]},
        # 映射姓名
        {"$lookup": {
            "from": "alumni",
            "let": {"person_ref_id": "$fives"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$person_ref_id.person_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"name_zh": 1, "_id": 0}}
            ],
            "as": 'persons'
        }},
        {"$group": {
            "_id": "$_id",
            "name": {"$first": "$name"},
            "end_date": {"$first": "$end_time"},
            "regions": {"$first": "$region"},
            "institutions": {"$first": "$institutions"},
            "persons": {"$push": "$persons"}
        }},
        {"$sort": {"end_date": -1}},
        {"$limit": 6},
    ]
    job_task_update_dept_to_es.apply_async(queue='es')
    docs = await aggregate_docs(activity_col, pipeline)
    for doc in docs:
        doc["id"] = str(doc["_id"])
        del doc["_id"]
        print(doc)
    return docs


@router.post("/desk/stats/register_records", description="活跃人才")
async def stats_activity_registers():
    """活动"""
    pipeline = [
        {"$match": {"is_deleted": {"$ne": True}, "is_attended": True}},
        # 活动报名人数 2排序
        {"$group": {
            "_id": "$person_id",
            "activities": {"$push": "$activity_id"},
            "activitiesNums": {"$sum": 1},
        }},
        {"$sort": {"activitiesNums": -1}},
        {"$limit": 12},
        {"$lookup": {
            "from": "activity",
            "let": {"activities_ref": "$activities"},
            "pipeline": [
                {"$match": {"$expr": {"$in": ["$_id", "$$activities_ref"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$sort": {"end_time": -1}},
                {"$limit": 1},
                {"$project": {"name": 1, "_id": 0, "end_time": 1, "start_time": 1}}
            ],
            "as": 'activities_objects'
        }},
        {"$lookup": {
            "from": "alumni",
            "let": {"person_ref_id": "$_id"},  # _id == person_id
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$person_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"name_zh": 1, "_id": 0, "name": 1, "identify_photo": 1,
                              "nationality": 1, "gender": 1, "job_title": 1, "cur_institution_department": 1,
                              "cur_institution_name": 1}}
            ],
            "as": 'persons'
        }},
        {"$addFields": {"person_info": {"$first": "$persons"}}},
        {"$unset": ["persons", "activities"]}
    ]
    data = []
    docs = await aggregate_docs(activity_register_col, pipeline)
    for doc in docs:
        doc["id"] = str(doc["_id"])
        del doc["_id"]
        if doc.get("person_info"):
            data.append(doc)

    # 更新es
    job_task_institution_overview.apply_async(queue='es')
    job_task_update_activity_span.apply_async(queue='es')
    job_task_radar.apply_async(queue='es')

    return data[:6]


@router.post("/desk/stats/institutions", description="活跃机构")
async def stats_activity_registers():
    pipeline = [
        {"$match": {"is_deleted": {"$ne": True}, "level": 1, "_id": {"$in": [
            ObjectId("62b945cd9aebef53937fecc0"),
            ObjectId("62b945cd9aebef53937fecc1"),
            ObjectId("62b945cd9aebef53937fecc2"),
            ObjectId("62b945cd9aebef53937fecc4"),
            ObjectId("62b945cd9aebef53937fecc5"),
            ObjectId("62b945cd9aebef53937fecc6"),
            ObjectId("62b945cd9aebef53937fecc7"),
            ObjectId("62b945cd9aebef53937fecc8"),
            ObjectId("62b945cd9aebef53937fecc9"),
            ObjectId("62b945cd9aebef53937fecca"),
            ObjectId("62b945cd9aebef53937feccb")
        ]
        }}},
        # 管理活动
        {"$unset": ["update_time", "create_time", "in_kexie", "level", "served_people_num"]},
        {"$lookup": {
            "from": "activity",
            "let": {"institution_id_ref": "$_id"},
            "pipeline": [
                {"$match": {
                    "is_deleted": {"$ne": True},
                    "$expr": {"$or": [
                        {"$eq": ["$$institution_id_ref", "$institution_id"]},
                        {"$in": ["$$institution_id_ref", "$co_inst_ids"]}
                    ]}
                },
                },
                {"$sort": {"end_time": -1}},
                {"$project": {"_id": 1, "name": 1, "start_time": 1, "end_time": 1}},
            ],
            "as": 'activities'
        }},
        #
        {"$addFields": {"numOfActivities": {"$size": "$activities"}}},
        {"$addFields": {"latestOfActivities": {"$first": "$activities"}}},

        {"$lookup": {
            "from": "activity_register",
            "let": {"activity_ref": "$activities"},
            "pipeline": [
                {"$match": {"$expr": {"$in": ["$activity_id", "$$activity_ref._id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"_id": 1}}

            ],
            "as": 'participants'
        }},
        {"$addFields": {"numOfParticipants": {"$size": "$participants"}}},
        {"$unset": ["participants", "activities", "latestOfActivities._id"]},

    ]
    job_task_update_dept_to_es.apply_async(queue='es')
    docs = await aggregate_docs(institution_col, pipeline)
    for doc in docs:
        doc["id"] = str(doc["_id"])
        del doc["_id"]
    return docs


@router.post("/desk/stats/register_records/by-month", description="活跃人数")
async def stats_activity_registers(query: ActivityStatisticParams):
    _year = query.year if query.year else datetime.utcnow().year
    from_date = datetime(_year, 1, 1) - timedelta(hours=8)
    to_date = datetime(_year + 1, 1, 1) - timedelta(hours=8)
    year_range = {"$gte": from_date,
                  "$lt": to_date}

    pipeline = [
        {"$match": {"end_time": year_range, "is_deleted": {"$ne": True}}},
        {"$project": {"start_time:": 1, "end_time": 1, "co_inst_ids": 1, "institution_id": 1, "activity_type": 1}},
        {"$lookup": {
            "from": "activity_register",
            "let": {"activity_ref_id": "$_id"},
            "pipeline": [
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$match": {"$expr": {"$eq": ["$activity_id", "$$activity_ref_id"]}}},
                {"$project": {"_id": 1}}
            ],
            "as": 'participants'
        }},
        {"$addFields": {"numOfParticipants": {"$size": "$participants"}}},
        {"$facet": {
            # 根据年获得活动数据
            "byMonth": [
                {"$group": {
                    "_id": {
                        "month": {"$month": "$end_time"},
                    },
                    "sum_val": {"$sum": "$numOfParticipants"}
                }},
                {"$sort": {"_id.month": 1}},
                {"$project": {"month": "$_id.month", "cumulative": "$sum_val", "_id": 0}}
            ],

        }}

    ]
    docs = await aggregate_docs(activity_col, pipeline)
    for m in range(1, 13):
        is_exits = [item for item in docs[0]['byMonth'] if item['month'] == m]
        if not is_exits:
            docs[0]['byMonth'].append({
                "month": m,
                "cumulative": 0
            })
    docs[0]['byMonth'] = sorted(docs[0]['byMonth'], key=lambda x: x["month"])
    return docs


@router.post("/desk/stats/activities/by-month-year", description="活动季度")
async def stats_activity_registers(query: ActivityStatisticParams):
    _year = query.year if query.year else datetime.utcnow().year
    from_date = datetime(_year, 1, 1) - timedelta(hours=8)
    to_date = datetime(_year + 1, 1, 1) - timedelta(hours=8)
    year_range = {"$gte": from_date,
                  "$lt": to_date}
    pipeline = [
        {"$match": {"end_time": year_range, "is_deleted": {"$ne": True}}},
        {"$project": {"start_time:": 1, "end_time": 1, "co_inst_ids": 1, "institution_id": 1, "activity_type": 1}},

        {"$facet": {
            # 月度
            "byMonth": [
                {"$group": {
                    "_id": {
                        "perMonth": {"$month": "$end_time"},
                    },
                    "total_participants": {"$sum": 1}
                }},
                {"$project": {"month": "$_id.perMonth", "total_participants": "$total_participants", "_id": 0}}
            ]
        }}
    ]

    docs = await aggregate_docs(activity_col, pipeline)
    for m in range(1, 13):
        is_exits = [item for item in docs[0]['byMonth'] if item['month'] == m]
        if not is_exits:
            docs[0]['byMonth'].append({
                "month": m,
                "total_participants": 0
            })
    docs[0]['byMonth'] = sorted(docs[0]['byMonth'], key=lambda x: x["month"])
    return docs
